package com.qf.driver.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.qf.common.bean.R;
import com.qf.common.constant.CommonConstant;
import com.qf.common.dto.CmdParamDto;
import com.qf.common.dto.DeviceDto;
import com.qf.common.dto.ProductDto;
import com.qf.common.model.DeviceCmd;
import com.qf.common.model.QfDevice;
import com.qf.common.model.QfDeviceTopic;
import com.qf.common.model.QfProduct;
import com.qf.common.utils.JsonUtil;
import com.qf.driver.feign.DeviceFeign;
import com.qf.driver.feign.ProductFeign;
import com.qf.driver.mqtt.bean.MqttProperties;
import com.qf.driver.mqtt.handler.MqttSendHandler;
import com.qf.driver.service.CommandService;
import com.qf.driver.service.DeviceTopicService;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Select;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.ReactiveListCommands;
import org.springframework.stereotype.Service;

import javax.xml.ws.ServiceMode;
import java.util.Date;
import java.util.List;

/**
 * @author 千锋健哥
 */
@Service
@Slf4j
public class CommandServiceImpl implements CommandService {

    @Autowired
    private DeviceTopicService deviceTopicService;

    @Autowired
    private MqttSendHandler mqttSendHandler;

    @Autowired
    private MqttProperties mqttProperties;

    @Autowired
    private DeviceFeign deviceFeign;

    @Autowired
    private ProductFeign productFeign;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public Boolean send(CmdParamDto dto) {

        //1. 通过设备key, 获取topic主题列表, 每个设备都有一对topic
        List<QfDeviceTopic> topicList = deviceTopicService.findTopicByDeviceKey(dto.getDeviceKey());

        //2. 将dto传入的指令内容, 转换成json格式字符串
        String cmd = JsonUtil.toJsonString(dto);

        //3. 从topic主题列表中找到, emqx中发送指令的topic主题
        ///发送指令的topic主题格式 : /qfjava/device/ctrl/设备key
        String topicName = null;
        if (topicList != null) {
            for (QfDeviceTopic topic : topicList) {
                if(topic.getTopic().contains("/qfjava/device/ctrl")) {
                    topicName = topic.getTopic();
                }
            }
        }

        //4. 调用mqtt接口, 发送指令
        try {
            mqttSendHandler.sendToMqtt(topicName, mqttProperties.getQos(), cmd);
        } catch (Exception e) {
            log.info("[driver-mqtt设备中心]发送指令异常, 发送内容:" + cmd);
        }

        //5. 封装指令日志实体
        //根据设备key, 查对应的设备实体
        DeviceDto deviceDto = new DeviceDto();
        deviceDto.setDeviceKey(dto.getDeviceKey());
        R<List> deviceResult = deviceFeign.findAreaAll(deviceDto);
        if (deviceResult != null) {
            List deviceList = deviceResult.getData();
            if(deviceList != null && deviceList.size() > 0) {
                QfDevice device = BeanUtil.toBean(deviceList.get(0), QfDevice.class);

                DeviceCmd deviceCmd = new DeviceCmd();
                //指令名称
                deviceCmd.setCmdName(dto.getCmdName());
                //设备key
                deviceCmd.setDeviceKey(dto.getDeviceKey());
                //继电器编号
                deviceCmd.setDeviceSubCode(dto.getDeviceSubCode());
                //指令值
                deviceCmd.setValue(dto.getValue());
                //产品key
                R<QfProduct> productResult = productFeign.selectById(String.valueOf(device.getProductId()));
                deviceCmd.setProductKey(productResult.getData().getProductKey());
                //租户id
                deviceCmd.setTenantId(device.getTenantId());
                //创建时间
                deviceCmd.setCreateTime(new Date());

                //6. 将指令日志实体发送到rabbitmq的队列中
                rabbitTemplate.convertAndSend(CommonConstant.Rabbit.TOPIC_EXCHANGE_VALUE,
                        CommonConstant.Rabbit.ROUTING_DEVICE_CMD_PREFIX + "cmd",
                        deviceCmd);
            }

        }

        return true;
    }

}
